#!/usr/bin/perl
use warnings;
use strict;


#******************************************************************************
# File: 
#		perl.pl
# Recipe: 16.1
#		Gathering Output from a Program 
# Version:
#		0.1
# Author:
#   	Yubei Zhu
# Mail:
#		yubeizhu@gmail.com
# Created at:
#   	2012-08-25  
# Last Update:
#   	2012-08-25
# License: 
#		GPLv3	
#******************************************************************************

# Using backticks, we can use wildcards here
# The behavior in list/scalar context is different  
my $sSimpleOutput = `ls -dx /tmp/test/Test*`; # Scalar context
my @aSimpleOutput = `ls -dx /tmp/test/Test*`; # List context


# Pls pay attention to the /n in element
# The output exactly is the same format as it in STDOUT
print "Scalar context:[$sSimpleOutput]\n";
print "List context:[@aSimpleOutput]\n"; 

print "==============================\n";
my @aOutputs = ReadFromCmd("ls /root");
print "Outputs: [@aOutputs]\n";

WriteToCmd("/tmp","cat");

# Recipe 16.4 Reading or Writing to Another Program
sub ReadFromCmd
#*****************************************************************************
# PURPOSE: 
#       Reading from another program
# USAGE:   
#       ReadFromCmd( "ls -al" )
# PASSED ARGS:  
#	1. Scalar: #sCmd	
# RETURN ARGS:
#   In scalar context: the output string, 
#   In list context: the output string list
# $sError - Fail Error Message
#       None
#******************************************************************************
{
	my ( $sCmd ) = shift; 
	return 0 if not $sCmd;

	#$sArgument = ;
	my ( $sPid, $fhIn, @aContents );
	eval{
		$sPid = open( $fhIn, "$sCmd |");
	};
	return 0 if not $sPid or $@;
	
	while( <$fhIn> ){
		push @aContents, $_;
	}
	close( $fhIn ) or die "Can't finish reading program: $sCmd\n" if $sPid;

	return wantarray( ) ? @aContents : join("", @aContents );
}


# Recipe 16.4 Reading or Writing to Another Program
sub WriteToCmd
#*****************************************************************************
# PURPOSE: 
#       Writing to another program
# USAGE:   
#       WriteFromProgram( $sMessage, $sCmd )
# PASSED ARGS:  
#	1. Scalar/List Reference : message	
#	2. Scalar: command 		
# RETURN ARGS:
#	True or false
# $sError - Fail Error Message
#       None
#******************************************************************************
{
	my ( $Msg, $sCmd ) = @_; 
	return 0 if not $sCmd or not $Msg;

	
	my ( $sPid, $fhIn, @aContents );
	eval{
		$sPid = open( $fhIn, "| $sCmd");
	};
	return 0 if not $sPid or $@;
	my @aContents = ref($Msg) eq "ARRAY" ? @{ $Msg } : $Msg; 

	foreach ( @aContents ){
		print $fhIn $_;
	}
	close( $fhIn ) or die "Can't finish writing program: $sCmd\n";

	return 1;
}
 
